// Copyright Epic Games, Inc. All Rights Reserved.

#include "LyraSettingValueDiscrete_PerfStat.h"

#include "CommonUIVisibilitySubsystem.h"
#include "Performance/LyraPerformanceSettings.h"
#include "Performance/LyraPerformanceStatTypes.h"
#include "Settings/LyraSettingsLocal.h"

#include UE_INLINE_GENERATED_CPP_BY_NAME(LyraSettingValueDiscrete_PerfStat)

class ULocalPlayer;

#define LOCTEXT_NAMESPACE "LyraSettings"

//////////////////////////////////////////////////////////////////////

/**
 * 性能统计允许的游戏设置编辑条件类
 */
class FGameSettingEditCondition_PerfStatAllowed : public FGameSettingEditCondition
{
public:
	static TSharedRef<FGameSettingEditCondition_PerfStatAllowed> Get(ELyraDisplayablePerformanceStat Stat) // 获取性能统计允许的编辑条件
	{
		return MakeShared<FGameSettingEditCondition_PerfStatAllowed>(Stat); // 创建共享指针
	}

	FGameSettingEditCondition_PerfStatAllowed(ELyraDisplayablePerformanceStat Stat) // 构造函数
		: AssociatedStat(Stat) // 初始化关联统计
	{
	}

	//~FGameSettingEditCondition接口
	/**
	 * 收集编辑状态
	 */
	virtual void GatherEditState(const ULocalPlayer* InLocalPlayer, FGameSettingEditableState& InOutEditState) const override
	{
		const FGameplayTagContainer& VisibilityTags = UCommonUIVisibilitySubsystem::GetChecked(InLocalPlayer)->GetVisibilityTags(); // 获取可见性标签

		bool bCanShowStat = false; // 是否可以显示统计
		for (const FLyraPerformanceStatGroup& Group : GetDefault<ULyraPerformanceSettings>()->UserFacingPerformanceStats) // 遍历用户面对的性能统计组
		{
			if (Group.AllowedStats.Contains(AssociatedStat)) // 如果组允许此统计
			{
				const bool bShowGroup = (Group.VisibilityQuery.IsEmpty() || Group.VisibilityQuery.Matches(VisibilityTags)); // 检查是否显示组
				if (bShowGroup) // 如果显示组
				{
					bCanShowStat = true; // 可以显示统计
					break; // 跳出循环
				}
			}
		}

		if (!bCanShowStat) // 如果不能显示统计
		{
			InOutEditState.Hide(TEXT("统计未在ULyraPerformanceSettings中列出或被当前平台特性抑制")); // 隐藏设置
		}
	}
	//~FGameSettingEditCondition接口结束

private:
	ELyraDisplayablePerformanceStat AssociatedStat; // 关联统计
};

//////////////////////////////////////////////////////////////////////

/**
 * 构造函数
 */
ULyraSettingValueDiscrete_PerfStat::ULyraSettingValueDiscrete_PerfStat()
{
}

/**
 * 设置统计类型
 */
void ULyraSettingValueDiscrete_PerfStat::SetStat(ELyraDisplayablePerformanceStat InStat)
{
	StatToDisplay = InStat; // 设置要显示的统计类型
	SetDevName(FName(*FString::Printf(TEXT("PerfStat_%d"), (int32)StatToDisplay))); // 设置开发名称
	AddEditCondition(FGameSettingEditCondition_PerfStatAllowed::Get(StatToDisplay)); // 添加编辑条件
}

/**
 * 添加显示模式
 */
void ULyraSettingValueDiscrete_PerfStat::AddMode(FText&& Label, ELyraStatDisplayMode Mode)
{
	Options.Emplace(MoveTemp(Label)); // 添加选项标签
	DisplayModes.Add(Mode); // 添加显示模式
}

/**
 * 初始化时调用
 */
void ULyraSettingValueDiscrete_PerfStat::OnInitialized()
{
	Super::OnInitialized(); // 调用父类初始化方法

	AddMode(LOCTEXT("PerfStatDisplayMode_None", "无"), ELyraStatDisplayMode::Hidden); // 添加隐藏模式
	AddMode(LOCTEXT("PerfStatDisplayMode_TextOnly", "仅文本"), ELyraStatDisplayMode::TextOnly); // 添加仅文本模式
	AddMode(LOCTEXT("PerfStatDisplayMode_GraphOnly", "仅图表"), ELyraStatDisplayMode::GraphOnly); // 添加仅图表模式
	AddMode(LOCTEXT("PerfStatDisplayMode_TextAndGraph", "文本和图表"), ELyraStatDisplayMode::TextAndGraph); // 添加文本和图表模式
}

/**
 * 存储初始设置
 */
void ULyraSettingValueDiscrete_PerfStat::StoreInitial()
{
	const ULyraSettingsLocal* Settings = ULyraSettingsLocal::Get(); // 获取本地设置
	InitialMode = Settings->GetPerfStatDisplayState(StatToDisplay); // 存储初始模式
}

/**
 * 重置为默认值
 */
void ULyraSettingValueDiscrete_PerfStat::ResetToDefault()
{
	ULyraSettingsLocal* Settings = ULyraSettingsLocal::Get(); // 获取本地设置
	Settings->SetPerfStatDisplayState(StatToDisplay, ELyraStatDisplayMode::Hidden); // 设置性能统计显示状态为隐藏
	NotifySettingChanged(EGameSettingChangeReason::ResetToDefault); // 通知设置已更改
}

/**
 * 恢复到初始值
 */
void ULyraSettingValueDiscrete_PerfStat::RestoreToInitial()
{
	ULyraSettingsLocal* Settings = ULyraSettingsLocal::Get(); // 获取本地设置
	Settings->SetPerfStatDisplayState(StatToDisplay, InitialMode); // 设置性能统计显示状态为初始模式
	NotifySettingChanged(EGameSettingChangeReason::RestoreToInitial); // 通知设置已更改
}

/**
 * 根据索引设置离散选项
 */
void ULyraSettingValueDiscrete_PerfStat::SetDiscreteOptionByIndex(int32 Index)
{
	if (DisplayModes.IsValidIndex(Index)) // 如果显示模式索引有效
	{
		const ELyraStatDisplayMode DisplayMode = DisplayModes[Index]; // 获取显示模式

		ULyraSettingsLocal* Settings = ULyraSettingsLocal::Get(); // 获取本地设置
		Settings->SetPerfStatDisplayState(StatToDisplay, DisplayMode); // 设置性能统计显示状态
	}
	NotifySettingChanged(EGameSettingChangeReason::Change); // 通知设置已更改
}

/**
 * 获取离散选项索引
 */
int32 ULyraSettingValueDiscrete_PerfStat::GetDiscreteOptionIndex() const
{
	const ULyraSettingsLocal* Settings = ULyraSettingsLocal::Get(); // 获取本地设置
	return DisplayModes.Find(Settings->GetPerfStatDisplayState(StatToDisplay)); // 返回显示模式的索引
}

/**
 * 获取离散选项
 */
TArray<FText> ULyraSettingValueDiscrete_PerfStat::GetDiscreteOptions() const
{
	return Options; // 返回选项数组
}

#undef LOCTEXT_NAMESPACE